package io.bloom.webspider;

import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import javax.net.ssl.*;
import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

@Slf4j
public class OkHttpDownloader implements Downloader {
    private SpiderExtractor extractor = new SpiderExtractor();
    private OkHttpClient client;

    private SpiderDuplicateChecker duplicateChecker = new SpiderDuplicateChecker();

    public SpiderResponse download(final SpiderRequest request) {
        String requestUrl = request.getUrl();
        log.debug("download request:{}", requestUrl);
        try {
            Request req = new Request.Builder()
                    .url(requestUrl)
                    .build();
            Response resp = client().newCall(req).execute();

            SpiderResponse response = new SpiderResponse();
            response.setRequest(request);
            response.setStatus(resp.code());
            ResponseBody body = resp.body();
            if (body != null) {
                String html = body.string();
                response.setRawText(html);

                Map<String, Object> extractData = extractor.extract(html);
                response.setData(extractData);
                //noinspection unchecked
                List<String> nextLinks = (List<String>) extractData.get("nextLinks");
                duplicateChecker.filter(nextLinks);
                response.setLinks(nextLinks);
            }

            duplicateChecker.put(requestUrl);
            log.debug("finish request:{}", requestUrl);
            return response;
        } catch (IOException e) {
            log.error("error", e);
            return SpiderResponse.FAIL;
        }
    }

    private OkHttpClient client() {
        if (client == null) {
            client = new OkHttpClient()
                    .newBuilder()
                    .hostnameVerifier(new HostnameVerifier() {
                        public boolean verify(String s, SSLSession sslSession) {
                            return true;
                        }
                    })
//                    .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("cgate", 80)))
                    .build();
        }

        return client;
    }
}
